package com.goodiebag.protractorview;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.multimodalinput.event.TouchEvent;

import java.io.IOException;

import static ohos.agp.utils.TextAlignment.CENTER;
import static ohos.multimodalinput.event.TouchEvent.CANCEL;
import static ohos.multimodalinput.event.TouchEvent.POINT_MOVE;
import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_DOWN;
import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_UP;
import static ohos.multimodalinput.event.TouchEvent.OTHER_POINT_UP;

/**
 * This class implements a widget for android which is a semi-circular seekbar drawn like a protractor with ticks.
 * Tick angles can be defined, angle value can be drawn at a desired interval of angles.
 * Ticks are highlighted as the seekbar passes through the respective tick's angle.
 * Date : 10/01/17.
 *
 * @author Krishanu
 * @author Pavan
 * @author Koushik
 */
public class ProtractorView extends Component {
    private static final int MAX = 180;
    private final float DENSITY = 1;
    private RectFloat mArcRect = new RectFloat();

    // Paints required for drawing
    private Paint mArcPaint;
    private Paint mArcProgressPaint;
    private Paint mTickPaint;
    private Paint mTickProgressPaint;
    private Paint mTickTextPaint;
    private Paint mTickTextColoredPaint;

    // Arc related dimens
    private int mArcRadius = 0;
    private int mArcWidth = DensityUtil.dp2px(getContext(), 2);
    private int mArcProgressWidth = DensityUtil.dp2px(getContext(), 2);
    private boolean mRoundedEdges = true;

    // Thumb Drawable
    private PixelMapElement mThumb;

    // Thumb position related coordinates
    private int mTranslateX;
    private int mTranslateY;
    private int mThumbXPos;
    private int mThumbYPos;
    private int mAngleTextSize = DensityUtil.dp2px(getContext(), 15);
    private int mTickOffset = DensityUtil.dp2px(getContext(), 12);
    private int mTickLength = DensityUtil.dp2px(getContext(), 10);
    private int mTickWidth = DensityUtil.dp2px(getContext(), 2);
    private int mTickProgressWidth = DensityUtil.dp2px(getContext(), 2);
    private int mAngle = 0;
    private boolean mTouchInside = true;
    private boolean mEnabled = true;
    private TicksBetweenLabel mTicksBetweenLabel = TicksBetweenLabel.TWO;
    private int mTickIntervals = 15;
    private double mTouchAngle = 0;
    private float mTouchIgnoreRadius;
    /**
     * M on protractor view change listener
     */
    private OnProtractorViewChangeListener mOnProtractorViewChangeListener = null;
    private boolean isMeasured;

    /**
     * On protractor view change listener
     */
    public interface OnProtractorViewChangeListener {
        void onProgressChanged(ProtractorView protractorView, int progress, boolean fromUser);

        void onStartTrackingTouch(ProtractorView protractorView);

        void onStopTrackingTouch(ProtractorView protractorView);
    }

    /**
     * Ticks between label
     */
    public enum TicksBetweenLabel {
        ZERO, ONE, TWO, THREE
    }

    public ProtractorView(Context context) throws NotExistException, WrongTypeException, IOException {
        this(context, null);
    }

    public ProtractorView(Context context, AttrSet attrSet) throws NotExistException, WrongTypeException, IOException {
        this(context, attrSet, "");
    }

    public ProtractorView(Context context, AttrSet attrSet, String styleName) throws NotExistException,
            WrongTypeException, IOException {
        super(context, attrSet, styleName);
        init(attrSet);
        addDrawTask(new DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                if (!isMeasured) {
                    onMeasure(component);
                    isMeasured = true;
                }
                canvas.save();
                canvas.scale(1, -1, mArcRect.getCenter().getPointX(), mArcRect.getCenter().getPointY());
                Arc arc = new Arc(0, MAX, false);
                Arc arcProgress = new Arc(0, mAngle, false);
                canvas.drawArc(mArcRect, arc, mArcPaint);
                canvas.drawArc(mArcRect, arcProgress, mArcProgressPaint);
                canvas.restore();
                deal(canvas);
                if (mEnabled) {
                    // Draw the thumb nail
                    canvas.save();
                    canvas.scale(-1, 1, mArcRect.getCenter().getPointX(), mArcRect.getCenter().getPointY());
                    canvas.translate(mTranslateX - mThumbXPos, mTranslateY - mThumbYPos);
                    mThumb.drawToCanvas(canvas);
                    canvas.restore();
                }
            }
        });
        setTouchEventListener(new TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                if (mEnabled) {
                    switch (touchEvent.getAction()) {
                        case PRIMARY_POINT_DOWN:
                            if (ignoreTouch(touchEvent.getPointerPosition(0).getX(),
                                    touchEvent.getPointerPosition(0).getY())) {
                                return false;
                            }
                            onStartTrackingTouch();
                            updateOnTouch(touchEvent, true);
                            break;
                        case POINT_MOVE:
                            updateOnTouch(touchEvent, true);
                            break;
                        case PRIMARY_POINT_UP:
                        case OTHER_POINT_UP:
                            onStopTrackingTouch();
                            updateOnTouch(touchEvent, false);
                            break;
                        case CANCEL:
                            onStopTrackingTouch();
                            updateOnTouch(touchEvent, false);
                            break;
                    }
                    return true;
                }
                return true;
            }
        });
    }

    private void deal(Canvas canvas) {
        double slope;
        double startTickX;
        double startTickY;
        double endTickX;
        double endTickY;
        double midTickX;
        double midTickY;
        double thetaInRadians;
        double radiusOffset = mArcRadius + mTickOffset;

        /**
         * Mechanism to draw the tick and text.
         * Tan(theta) gives the slope.
         * Formula for a straight line is y = mx + c.
         * y is calculated for varying values of x and the ticks are drawn.
         */

        int count = mTicksBetweenLabel.ordinal();
        for (int i = 360; i >= 180; i -= mTickIntervals) {
            canvas.save();
            if (count == mTicksBetweenLabel.ordinal()) {
                canvas.translate(mArcRect.getCenter().getPointX(), mArcRect.getCenter().getPointY());
                thetaInRadians = Math.toRadians(i);
                slope = Math.tan(thetaInRadians);
                startTickX = (radiusOffset * Math.cos(thetaInRadians));
                midTickX = startTickX + (((mTickLength / 2)) * Math.cos(thetaInRadians));
                midTickY = slope * midTickX;
                canvas.drawText((mAngle <= 359 - i) ? mTickTextPaint : mTickTextColoredPaint,
                        "" + (360 - i), (float) midTickX, (float) midTickY);
                count = 0;
            } else {
                canvas.scale(-1, 1, mArcRect.getCenter().getPointX(), mArcRect.getCenter().getPointY());
                canvas.translate(mArcRect.getCenter().getPointX(), mArcRect.getCenter().getPointY());
                canvas.rotate(-180, 0, 0);
                thetaInRadians = Math.toRadians(360 - i);
                slope = Math.tan(thetaInRadians);
                startTickX = (radiusOffset * Math.cos(thetaInRadians));
                startTickY = slope * startTickX;
                endTickX = startTickX + ((mTickLength) * Math.cos(thetaInRadians));
                endTickY = slope * endTickX;
                Point startP = new Point((float) startTickX, (float) startTickY);
                Point endP = new Point((float) endTickX, (float) endTickY);
                canvas.drawLine(startP, endP, (mAngle <= 359 - i) ? mTickPaint : mTickProgressPaint);
                count++;
            }
            canvas.restore();
        }
    }

    private void onMeasure(Component component) {
        int height = component.getHeight();
        int width = component.getWidth();
        int min = Math.min(width, height);
        height = min / 2;
        float top = 0;
        float left = 0;
        int arcDiameter = 0;
        int tickEndToArc = (mTickOffset + mTickLength);
        arcDiameter = min - 2 * tickEndToArc;
        arcDiameter = (int) (arcDiameter - 2 * DensityUtil.dp2px(getContext(), 20) * DENSITY);
        mArcRadius = arcDiameter / 2;
        top = height - (mArcRadius);
        left = width / 2 - mArcRadius;
        mArcRect.left = left;
        mArcRect.top = top;
        mArcRect.right = left + arcDiameter;
        mArcRect.bottom = top + arcDiameter;
        mTranslateX = (int) mArcRect.getCenter().getPointX();
        mTranslateY = (int) mArcRect.getCenter().getPointY();
        int thumbAngle = mAngle;
        mThumbXPos = (int) (mArcRadius * Math.cos(Math.toRadians(thumbAngle)));
        mThumbYPos = (int) (mArcRadius * Math.sin(Math.toRadians(thumbAngle)));
        setTouchInside(mTouchInside);
        setWidth(width);
        setHeight(height + tickEndToArc);
    }

    /**
     * Init *
     *
     * @param attrSet attr set
     * @throws NotExistException  not exist exception
     * @throws WrongTypeException wrong type exception
     * @throws IOException        io exception
     */
    private void init(AttrSet attrSet) throws NotExistException, WrongTypeException, IOException {
        /**
         * Defaults, may need to link this into theme settings
         */
        ohos.global.resource.ResourceManager resManager = getContext().getResourceManager();
        int arcColor = resManager.getElement(ResourceTable.Color_progress_gray).getColor();
        int arcProgressColor = resManager.getElement(ResourceTable.Color_default_blue_light).getColor();
        int textColor = resManager.getElement(ResourceTable.Color_progress_gray).getColor();
        int textProgressColor = resManager.getElement(ResourceTable.Color_default_blue_light).getColor();
        int tickColor = resManager.getElement(ResourceTable.Color_progress_gray).getColor();
        int tickProgressColor = resManager.getElement(ResourceTable.Color_default_blue_light).getColor();
        int thumbHalfHeight = 0;
        int thumbHalfWidth = 0;
        /**
         * Convert all default dimens to pixels for current density
         */
        initlenths();

        if (attrSet != null) {
            PixelMapElement thumb = ResUtil.getPixelMapDrawable(getContext(), ResourceTable.Media_ring_unpress);
            if (thumb != null) {
                mThumb = thumb;
            }
            thumbHalfHeight = mThumb.getHeight() / 2;
            thumbHalfWidth = mThumb.getWidth() / 2;
            mThumb.setBounds(-thumbHalfWidth, -thumbHalfHeight, thumbHalfWidth, thumbHalfHeight);
            mAngleTextSize = (int) AttrUtils.getDimensionFromAttr(attrSet, "angleTextSize", mAngleTextSize);
            mArcProgressWidth = (int) AttrUtils.getDimensionFromAttr(attrSet, "progressWidth", mArcProgressWidth);
            mTickOffset = (int) AttrUtils.getDimensionFromAttr(attrSet, "tickOffset", mTickOffset);
            mTickLength = (int) AttrUtils.getDimensionFromAttr(attrSet, "tickLength", mTickLength);
            mArcWidth = (int) AttrUtils.getDimensionFromAttr(attrSet, "arcWidth", mArcWidth);
            // Integers
            mAngle = AttrUtils.getIntFromAttr(attrSet, "angle", mAngle);
            mTickIntervals = AttrUtils.getIntFromAttr(attrSet, "tickIntervals", mTickIntervals);
            // Colors
            arcColor = AttrUtils.getColorFromAttr(attrSet, "arcColor", arcColor);
            arcProgressColor = AttrUtils.getColorFromAttr(attrSet, "arcProgressColor", arcProgressColor);
            textColor = AttrUtils.getColorFromAttr(attrSet, "textColor", textColor);
            textProgressColor = AttrUtils.getColorFromAttr(attrSet, "textProgressColor", textProgressColor);
            // 刻度线颜色
            tickColor = AttrUtils.getColorFromAttr(attrSet, "tickColor", tickColor);
            tickProgressColor = AttrUtils.getColorFromAttr(attrSet, "tickProgressColor", tickProgressColor);
            // Boolean
            mRoundedEdges = AttrUtils.getBooleanFromAttr(attrSet, "roundEdges", mRoundedEdges);
            mEnabled = AttrUtils.getBooleanFromAttr(attrSet, "enabled", mEnabled);
            mTouchInside = AttrUtils.getBooleanFromAttr(attrSet, "touchInside", mTouchInside);
            int ordinal = AttrUtils.getIntFromAttr(attrSet, "ticksBetweenLabel", mTicksBetweenLabel.ordinal());
            mTicksBetweenLabel = TicksBetweenLabel.values()[ordinal];
        }
        /**
         * Creating and configuring the paints as  required.
         */
        mAngle = (mAngle > MAX) ? MAX : ((mAngle < 0) ? 0 : mAngle);

        initPaints(arcColor, arcProgressColor, textColor, textProgressColor, tickColor, tickProgressColor);
    }

    private void initPaints(int arcColor, int arcProgressColor,
                            int textColor, int textProgressColor,
                            int tickColor, int tickProgressColor) {
        mArcPaint = new Paint();
        mArcPaint.setColor(new Color(arcColor));
        mArcPaint.setAntiAlias(true);
        mArcPaint.setStyle(Paint.Style.STROKE_STYLE);
        mArcPaint.setStrokeWidth(mArcWidth);

        mArcProgressPaint = new Paint();
        mArcProgressPaint.setColor(new Color(arcProgressColor));
        mArcProgressPaint.setAntiAlias(true);
        mArcProgressPaint.setStyle(Paint.Style.STROKE_STYLE);
        mArcProgressPaint.setStrokeWidth(mArcProgressWidth);

        if (mRoundedEdges) {
            mArcPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
            mArcProgressPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        }

        mTickPaint = new Paint();
        mTickPaint.setColor(new Color(tickColor));
        mTickPaint.setAntiAlias(true);
        mTickPaint.setStyle(Paint.Style.STROKE_STYLE);
        mTickPaint.setStrokeWidth(mTickWidth);

        mTickProgressPaint = new Paint();
        mTickProgressPaint.setColor(new Color(tickProgressColor));
        mTickProgressPaint.setAntiAlias(true);
        mTickProgressPaint.setStyle(Paint.Style.STROKE_STYLE);
        mTickProgressPaint.setStrokeWidth(mTickProgressWidth);

        mTickTextPaint = new Paint();
        mTickTextPaint.setColor(new Color(textColor));
        mTickTextPaint.setAntiAlias(true);
        mTickTextPaint.setStyle(Paint.Style.FILL_STYLE);
        mTickTextPaint.setTextSize(mAngleTextSize);
        mTickTextPaint.setTextAlign(CENTER);

        mTickTextColoredPaint = new Paint();
        mTickTextColoredPaint.setColor(new Color(textProgressColor));
        mTickTextColoredPaint.setAntiAlias(true);
        mTickTextColoredPaint.setStyle(Paint.Style.FILL_STYLE);
        mTickTextColoredPaint.setTextSize(mAngleTextSize);
        mTickTextColoredPaint.setTextAlign(CENTER);
    }

    private void initlenths() {
        mArcWidth = (int) (mArcWidth * DENSITY);
        mArcProgressWidth = (int) (mArcProgressWidth * DENSITY);
        mAngleTextSize = (int) (mAngleTextSize * DENSITY);
        mTickOffset = (int) (mTickOffset * DENSITY);
        mTickLength = (int) (mTickLength * DENSITY);
        mTickWidth = (int) (mTickWidth * DENSITY);
        mTickProgressWidth = (int) (mTickProgressWidth * DENSITY);
    }

    private void onStartTrackingTouch() {
        if (mOnProtractorViewChangeListener != null) {
            mOnProtractorViewChangeListener.onStartTrackingTouch(this);
        }
    }

    private void onStopTrackingTouch() {
        if (mOnProtractorViewChangeListener != null) {
            mOnProtractorViewChangeListener.onStopTrackingTouch(this);
        }
    }


    private boolean ignoreTouch(float xPos, float yPos) {
        boolean ignore = false;
        float xCoordinate = xPos - mTranslateX;
        float yCoordinate = yPos - mTranslateY;

        float touchRadius = (float) Math.sqrt(((xCoordinate * xCoordinate) + (yCoordinate * yCoordinate)));
        if (touchRadius < mTouchIgnoreRadius || touchRadius > (mArcRadius + mTickLength + mTickOffset)) {
            ignore = true;
        }
        return ignore;
    }

    private void updateOnTouch(TouchEvent event, boolean pressState) {
        boolean ignoreTouch = ignoreTouch(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY());
        if (ignoreTouch) {
            setPressState(pressState);
            PixelMapElement thumb;
            if (isPressed()) {
                thumb = ResUtil.getPixelMapDrawable(getContext(), ResourceTable.Media_ring_pressed);
            } else {
                thumb = ResUtil.getPixelMapDrawable(getContext(), ResourceTable.Media_ring_unpress);
            }

            if (thumb != null) {
                mThumb = thumb;
            }
            int thumbHalfHeight = 0;
            int thumbHalfWidth = 0;
            thumbHalfHeight = mThumb.getHeight() / 2;
            thumbHalfWidth = mThumb.getWidth() / 2;
            mThumb.setBounds(-thumbHalfWidth, -thumbHalfHeight, thumbHalfWidth, thumbHalfHeight);
            invalidate();
            return;
        }
        setPressState(pressState);
        mTouchAngle = getTouchDegrees(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY());
        onProgressRefresh((int) mTouchAngle, true);
    }


    private double getTouchDegrees(float xPos, float yPos) {
        float xCoordinate = xPos - mTranslateX;
        float yCoordinate = yPos - mTranslateY;
        xCoordinate = -xCoordinate;

        // convert to arc Angle
        double angle = Math.toDegrees(Math.atan2(yCoordinate, xCoordinate) + (Math.PI));
        if (angle > 270) {
            angle = 0;
        } else if (angle > 180) {
            angle = 180;
        }
        return angle;
    }

    private void onProgressRefresh(int angle, boolean fromUser) {
        updateAngle(angle, fromUser);
    }

    private void updateAngle(int angle, boolean fromUser) {
        mAngle = (angle > MAX) ? MAX : (angle < 0) ? 0 : angle;

        if (mOnProtractorViewChangeListener != null) {
            mOnProtractorViewChangeListener.onProgressChanged(this, mAngle, fromUser);
        }
        updateThumbPosition();
        PixelMapElement thumb;
        if (isPressed()) {
            thumb = ResUtil.getPixelMapDrawable(getContext(), ResourceTable.Media_ring_pressed);
        } else {
            thumb = ResUtil.getPixelMapDrawable(getContext(), ResourceTable.Media_ring_unpress);
        }

        if (thumb != null) {
            mThumb = thumb;
        }
        int thumbHalfHeight = 0;
        int thumbHalfWidth = 0;
        thumbHalfHeight = mThumb.getHeight() / 2;
        thumbHalfWidth = mThumb.getWidth() / 2;
        mThumb.setBounds(-thumbHalfWidth, -thumbHalfHeight, thumbHalfWidth, thumbHalfHeight);

        invalidate();
    }

    private void updateThumbPosition() {
        int thumbAngle = mAngle;
        mThumbXPos = (int) (mArcRadius * Math.cos(Math.toRadians(thumbAngle)));
        mThumbYPos = (int) (mArcRadius * Math.sin(Math.toRadians(thumbAngle)));
    }


    /**
     * Gets touch inside *
     *
     * @return the touch inside
     */
    public boolean getTouchInside() {
        return mTouchInside;
    }


    /**
     * Sets touch inside *
     *
     * @param isEnabled is enabled
     */
    public void setTouchInside(boolean isEnabled) {
        int thumbHalfheight = (int) mThumb.getHeight() / 2;
        int thumbHalfWidth = (int) mThumb.getWidth() / 2;
        mTouchInside = isEnabled;
        if (mTouchInside) {
            mTouchIgnoreRadius = (float) (mArcRadius / 1.5);
        } else {
            mTouchIgnoreRadius = mArcRadius - Math.min(thumbHalfWidth, thumbHalfheight);
        }
    }

    /**
     * Sets on protractor view change listener *
     *
     * @param onProtractorViewChangeListener onProtractorViewChangeListener
     */
    public void setOnProtractorViewChangeListener(OnProtractorViewChangeListener onProtractorViewChangeListener) {
        mOnProtractorViewChangeListener = onProtractorViewChangeListener;
    }

    /**
     * Gets on protractor view change listener *
     *
     * @return the on protractor view change listener
     */
    public OnProtractorViewChangeListener getOnProtractorViewChangeListener() {
        return mOnProtractorViewChangeListener;
    }

    /**
     * Gets angle *
     *
     * @return the angle
     */
    public int getAngle() {
        return mAngle;
    }

    /**
     * Sets angle *
     *
     * @param angle angle
     */
    public void setAngle(int angle) {
        this.mAngle = angle;
        onProgressRefresh(mAngle, false);
    }

    /**
     * Is enabled boolean
     *
     * @return the boolean
     */
    public boolean isEnabled() {
        return mEnabled;
    }

    /**
     * Sets enabled *
     *
     * @param enabled enabled
     */
    public void setEnabled(boolean enabled) {
        this.mEnabled = enabled;
        invalidate();
    }

    /**
     * Gets progress color *
     *
     * @return the progress color
     */
    public int getProgressColor() {
        return mArcProgressPaint.getColor().getValue();
    }

    /**
     * Sets progress color *
     *
     * @param color color
     */
    public void setProgressColor(int color) {
        mArcProgressPaint.setColor(new Color(color));
        invalidate();
    }

    /**
     * Gets arc color *
     *
     * @return the arc color
     */
    public int getArcColor() {
        return mArcPaint.getColor().getValue();
    }

    /**
     * Sets arc color *
     *
     * @param color color
     */
    public void setArcColor(int color) {
        mArcPaint.setColor(new Color(color));
        invalidate();
    }

    /**
     * Gets arc progress width *
     *
     * @return the arc progress width
     */
    public int getArcProgressWidth() {
        return mArcProgressWidth;
    }

    /**
     * Sets arc progress width *
     *
     * @param arcProgressWidth arc progress width
     */
    public void setArcProgressWidth(int arcProgressWidth) {
        this.mArcProgressWidth = arcProgressWidth;
        mArcProgressPaint.setStrokeWidth(arcProgressWidth);
        invalidate();
    }

    /**
     * Gets arc width *
     *
     * @return the arc width
     */
    public int getArcWidth() {
        return mArcWidth;
    }

    /**
     * Sets arc width *
     *
     * @param arcWidth arc width
     */
    public void setArcWidth(int arcWidth) {
        this.mArcWidth = arcWidth;
        mArcPaint.setStrokeWidth(arcWidth);
        invalidate();
    }

    /**
     * Is rounded edges boolean
     *
     * @return the boolean
     */
    public boolean isRoundedEdges() {
        return mRoundedEdges;
    }

    /**
     * Sets rounded edges *
     *
     * @param roundedEdges rounded edges
     */
    public void setRoundedEdges(boolean roundedEdges) {
        this.mRoundedEdges = roundedEdges;
        if (roundedEdges) {
            mArcPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
            mArcProgressPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        } else {
            mArcPaint.setStrokeCap(Paint.StrokeCap.SQUARE_CAP);
            mArcPaint.setStrokeCap(Paint.StrokeCap.SQUARE_CAP);
        }
        invalidate();
    }

    /**
     * Gets angle text size *
     *
     * @return the angle text size
     */
    public int getAngleTextSize() {
        return mAngleTextSize;
    }

    /**
     * Sets angle text size *
     *
     * @param angleTextSize angle text size
     */
    public void setAngleTextSize(int angleTextSize) {
        this.mAngleTextSize = angleTextSize;
        invalidate();
    }

    /**
     * Gets tick offset *
     *
     * @return the tick offset
     */
    public int getTickOffset() {
        return mTickOffset;
    }

    /**
     * Sets tick offset *
     *
     * @param tickOffset tick offset
     */
    public void setTickOffset(int tickOffset) {
        this.mTickOffset = tickOffset;
    }

    /**
     * Gets tick length *
     *
     * @return the tick length
     */
    public int getTickLength() {
        return mTickLength;
    }

    /**
     * Sets tick length *
     *
     * @param tickLength tick length
     */
    public void setTickLength(int tickLength) {
        this.mTickLength = tickLength;
    }

    /**
     * Gets ticks between label *
     *
     * @return the ticks between label
     */
    public TicksBetweenLabel getTicksBetweenLabel() {
        return mTicksBetweenLabel;
    }

    /**
     * Sets ticks between label *
     *
     * @param ticksBetweenLabel ticks between label
     */
    public void setTicksBetweenLabel(TicksBetweenLabel ticksBetweenLabel) {
        this.mTicksBetweenLabel = mTicksBetweenLabel;
        invalidate();
    }

    /**
     * Gets tick intervals *
     *
     * @return the tick intervals
     */
    public int getTickIntervals() {
        return mTickIntervals;
    }

    /**
     * Sets tick intervals *
     *
     * @param tickIntervals tick intervals
     */
    public void setTickIntervals(int tickIntervals) {
        this.mTickIntervals = tickIntervals;
        invalidate();
    }
}
